package com.yzy.util.response;

import com.yzy.exception.GlobalExceptionMessage;
import com.yzy.exception.VisionException;
import eu.bitwalker.useragentutils.Browser;
import eu.bitwalker.useragentutils.RenderingEngine;
import eu.bitwalker.useragentutils.UserAgent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class ResponseUtils {

    // private static final ExecutorService EXECUTOR_SERVICE = Executors.newSingleThreadExecutor();
    private static final ExecutorService EXECUTOR_SERVICE = new ThreadPoolExecutor(1, 1,
                                   0L,TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>());

    private static final String RESPONSE_HANDLE_SUCCESS_MESSAGE = GlobalExceptionMessage.INTERNAL_SERVER_HANDLE_SUCCESSFUL;

    private static final String RESPONSE_HANDLE_ERROR_MESSAGE = GlobalExceptionMessage.INTERNAL_SERVER_HANDLE_FAILED;

    public static ResponseEntity<?> OK() {
        WRITE2LOG(HttpStatus.OK, RESPONSE_HANDLE_SUCCESS_MESSAGE);
        return new ResponseEntity<>("OK", HttpStatus.OK);
    }



    /**
     * 下载文件
     * @param file
     * @return
     */
    public static ResponseEntity<?> OK(HttpServletRequest request, File file, String fileName) throws UnsupportedEncodingException {
        WRITE2LOG(HttpStatus.OK, RESPONSE_HANDLE_SUCCESS_MESSAGE);
        HttpHeaders headers = new HttpHeaders();
        if (isIEExplorer(request) || isEDGEExplorer(request)) {
            fileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.name());
        } else {
            fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
        }
        headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=\"" + fileName + "\"");
        headers.setContentType(MediaType.parseMediaType("application/octet-stream"));
        headers.setContentLength(file.length());
        return new ResponseEntity<>(new FileSystemResource(file), headers, HttpStatus.OK);
    }

    /**
     * 响应数据
     * @param data
     * @return
     */
    public static ResponseEntity<?> OK(Object data) {
        WRITE2LOG(HttpStatus.OK, RESPONSE_HANDLE_SUCCESS_MESSAGE);
/*        if(data instanceof Collection) {
            Collection datas = (Collection) data;
            Object[] objects = datas.toArray();
            if(objects.length == 1) {
                data = objects[0];
            }
        }*/
        return new ResponseEntity<>(data, HttpStatus.OK);
    }

    public static Boolean isIEExplorer(HttpServletRequest request) {
        //获取浏览器信息
        String userAgentMsg = request.getHeader(HttpHeaders.USER_AGENT);
        //转成UserAgent对象
        UserAgent userAgent = UserAgent.parseUserAgentString(userAgentMsg);
        //获取浏览器信息
        Browser browser = userAgent.getBrowser();
        //获取系统信息
        //OperatingSystem os = userAgent.getOperatingSystem();
        //系统名称
        //String system = os.getName();
        //浏览器名称
        //String browserName = browser.getName();
        return RenderingEngine.TRIDENT.equals(browser.getRenderingEngine());
    }

    public static Boolean isEDGEExplorer(HttpServletRequest request) {
        //获取浏览器信息
        String userAgentMsg = request.getHeader("User-Agent");
        //转成UserAgent对象
        UserAgent userAgent = UserAgent.parseUserAgentString(userAgentMsg);
        //获取浏览器信息
        Browser browser = userAgent.getBrowser();
        return RenderingEngine.EDGE_HTML.equals(browser.getRenderingEngine());
    }

/*    public static ResponseEntity<?> OK(Object data) {
        WRITE2LOG(HttpStatus.OK, RESPONSE_HANDLE_SUCCESS_MESSAGE);
        return new ResponseEntity(new ResponseObj(HttpStatus.OK, RESPONSE_HANDLE_SUCCESS_MESSAGE, data), HttpStatus.OK);
    }

    public static ResponseEntity<?> OK(Object data, String message) {
        WRITE2LOG(HttpStatus.OK, message);
        return new ResponseEntity(new ResponseObj(HttpStatus.OK, message, data), HttpStatus.OK);
    }*/

    public static ResponseEntity<?> ERROR(VisionException e) {
        WRITE2LOG(e.getStatus(), getExceptionStackTrace(e));
        return new ResponseEntity<>(new ResponseObj(e.getStatus(), e.getMessage(), e.getData()), e.getStatus());
    }

    public static ResponseEntity<?> ERROR(HttpStatus status, Exception e) {
        WRITE2LOG(status, getExceptionStackTrace(e));
        return new ResponseEntity<>(new ResponseObj(status, RESPONSE_HANDLE_ERROR_MESSAGE, e.getMessage()), status);
    }

    private static String getExceptionStackTrace(Exception e) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        e.printStackTrace(pw);
        return sw.toString();
    }

    private static void WRITE2LOG(HttpStatus status, String message) {
        Runnable task = () -> {
            if (HttpStatus.OK.equals(status)) {
                log.info(message);
            } else {
                log.error(message);
            }
        };
        EXECUTOR_SERVICE.execute(task);
    }
}
